const { TelegramClient } = require('telegram');
const { StringSession } = require('telegram/sessions');
const { Api } = require('telegram');
const { NewMessage } = require('telegram/events');
const fs = require('fs');       
const path = require('path');    
const yaml = require('js-yaml'); 

let tgConfig = {
  apiId : "",
  apiHash : "",
  callbackUrl : "http://127.0.0.1:8080/telegram_callback"
};

try {
    const fileContents = fs.readFileSync(path.resolve(__dirname, './config.yml'), 'utf8');
    const config = yaml.load(fileContents);
    // console.log(config)
    tgConfig.apiId = config.apiId
    tgConfig.apiHash = config.apiHash
     if (config.callbackUrl) tgConfig.callbackUrl = config.callbackUrl
    // config = config;
    // console.log('✅ 配置加载成功:', tgConfig);
} catch (e) {
    console.error('❌ 读取配置失败:', e);
}

const apiId = tgConfig.apiId;
const apiHash = tgConfig.apiHash;

const { SocksProxyAgent } = require('socks-proxy-agent');
const agent = new SocksProxyAgent('socks5h://127.0.0.1:10808');

// const { HttpsProxyAgent } = require('https-proxy-agent');
// const agent = new HttpsProxyAgent('http://127.0.0.1:10808'); // Clash 默认 HTTP 端口


const session = new StringSession('');
const client = new TelegramClient(session, apiId, apiHash, {
  connectionRetries: 5,
  autoReconnect: true,
  requestRetries: 3,
  webSocketOptions: { agent },
});

async function sendCode(phoneNumber) {
  await client.connect();
  const result = await client.sendCode({
    apiId,
    apiHash,
    settings: new Api.CodeSettings({}),
  }, phoneNumber);
  return result.phoneCodeHash;
}

async function login(phoneNumber, code, password) {
  try {
    await client.connect();

    if (await client.checkAuthorization()) {
      console.log("用户已登录，无需重复登录");
      return client;
    }

    const user = await client.signInUser(
      { apiId, apiHash },
      {
        phoneNumber: async () => phoneNumber,
        phoneCode: async () => code,
        password: async () => password,
        onError: async (err) => {
          console.error('❌ 登录错误：', err.message);
          await client.disconnect();
          client.session = null;
        },
      }
    );

    const r = {
      msg: "登录成功",
      token: client.session.save(),
    };
    console.log('✅ 登录成功');
    console.log('📦 session 字符串：', r);
    return r;
  } catch (err) {
    console.error('❌ 登录失败：', err);
    try {
      await client.disconnect();
      client.session = null;
    } catch (e) {
      console.warn('⚠️ 关闭连接时出错：', e);
    }
    throw err;
  }
}

async function getUserGroups(client) {
  if (!client.connected) {
    await client.connect();
  }
  if (!(await client.checkAuthorization())) {
    console.log("未登录，无法获取群组");
    return null;
  }

  let allChats = [];
  let offsetDate = 0;
  let offsetId = 0;
  let offsetPeer = new Api.InputPeerEmpty();
  const limit = 100;

  while (true) {
    const dialogs = await client.invoke(new Api.messages.GetDialogs({
      offsetDate,
      offsetId,
      offsetPeer,
      limit,
      hash: 0,
    }));

    allChats = allChats.concat(dialogs.chats);

    if (dialogs.chats.length < limit) break;

    const lastDialog = dialogs.dialogs[dialogs.dialogs.length - 1];
    offsetDate = lastDialog.topMessage?.date || offsetDate;
    offsetId = lastDialog.topMessage?.id || offsetId;
    offsetPeer = lastDialog.peer;
  }

  // 过滤普通群组 Chat 和超级群组 Channel (megagroup === true)
  return allChats.filter(chat => {
    if (chat.className === 'Chat') {
      return true; // 普通群组
    }
    if (chat.className === 'Channel' && chat.megagroup === true) {
      return true; // 超级群组
    }
    return false; // 过滤频道等其他
  });
}


async function createClientFromSession( sessionString) {
  const stringSession = new StringSession(sessionString);

  const client = new TelegramClient(stringSession, apiId, apiHash, {
    connectionRetries: 5,
    webSocketOptions: { agent },
  });

  try {
    await client.connect();
    if (!(await client.checkAuthorization())) {
      throw new Error('❌ session 无效或已过期，请重新登录');
    }
    console.log('✅ 已使用 session 成功连接 Telegram');
    return client;
  } catch (err) {
    console.error('❌ 连接失败:', err.message);
    throw err;
  }
}

async function logoutFromSession(sessionString) {
  const stringSession = new StringSession(sessionString);
  const client = new TelegramClient(stringSession, apiId, apiHash, {
    connectionRetries: 5,
    webSocketOptions: { agent },
  });

  try {
    await client.connect();

    if (!(await client.checkAuthorization())) {
      console.log('ℹ️ 当前 session 未登录，无需注销');
      return;
    }

    await client.invoke(new Api.auth.LogOut());
    console.log('✅ 已成功注销登录');

  } catch (err) {
    console.error('❌ 注销失败：', err.message);
    throw err;
  } finally {
    try {
      await client.disconnect();
    } catch (e) {
      console.warn('⚠️ disconnect 时异常（可忽略）：', e.message);
    }
    // ❌ 千万不要再手动 client.session = null；
  }

  return true;
}


/**
 * 给指定用户发送私信
 * @param {TelegramClient} client 已连接的 TelegramClient 实例
 * @param {bigint} userId 用户ID（BigInt类型）
 * @param {type} accessHash 用户accessHash 
 * @param {string} message 要发送的文本消息
 */
async function sendPrivateMessageToUser(client, userId,accessHash, message) {
  try {
    // 获取用户完整实体，拿到 accessHash
    const userEntity = await client.getEntity(userId);


    // 发送消息
    await client.sendMessage(userEntity, { message });

    console.log(`✅ 已成功给用户 ${userId} 发送消息: ${message}`);
    return true
  } catch (err) {
    console.error(`❌ 给用户 ${userId} 发送消息失败:`, err);
    return false
  }
}

// 连接并启动监听
async function startListening(sessionString = '') {
  try {
    // 如果有session字符串则使用它
    if (sessionString) {
      client.session = new StringSession(sessionString);
    }
 
    await client.connect();
    
    // 检查授权
    if (!(await client.checkAuthorization())) {
      throw new Error('未授权，请先登录');
    }
 
    console.log('✅ 已连接到Telegram，开始监听私聊消息...');
 
    // 添加新消息事件监听器
    client.addEventHandler(async (event) => {
      // 只处理私聊消息
      if (event.isPrivate) {
        const message = event.message;
        const sender = await message.getSender();
        // 准备回调数据
        const callbackData = {
          messageId: message.id.toString(),
          senderId: sender.id.toString(),
          sender: {
            id: sender.id.toString(),
            firstName: sender.firstName || '',
            lastName: sender.lastName || '',
            username: sender.username || '',
            phone: sender.phone || ''
          },
          text: message.message,
          date: message.date,
          isOutgoing: message.out
        };

        console.log(callbackData)
        // 回调给易语言程序
        try {
          const response = await axios.post(tgConfig.callbackUrl, callbackData, {
            headers: { 'Content-Type': 'application/json' },
            timeout: 5000 // 5秒超时
          });
          console.log('📢 回调成功:', response.data);
        } catch (error) {
          console.error('❌ 回调失败:', error.message);
        }
      }
    }, new NewMessage({}));
 
  } catch (err) {
    console.error('❌ 启动监听失败:', err);
    process.exit(1);
  }
}
module.exports = {
  startListening,
  sendCode,
  login,
  createClientFromSession,
  getUserGroups,
  logoutFromSession,
  sendPrivateMessageToUser
};
